package com.cssl.service.impl;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.cssl.domain.DtsAd;
import com.cssl.domain.DtsAdmin;
import com.cssl.domain.DtsRole;
import com.cssl.domain.dto.DtsAdminDto;
import com.cssl.domain.vo.DtsAdminVO;
import com.cssl.mapper.DtsAdminMapper;
import com.cssl.service.DtsAdminService;
import com.cssl.util.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class DtsAdminServiceImpl implements DtsAdminService {
    @Autowired
    private StringRedisTemplate template;
    @Autowired
    private DtsAdminMapper dtsAdminMapper;
    @Autowired
    private RedisUtil redisUtil;
    //验证码key
    private String key;

    @Override
    public Result login(String name, String password, String code) {
        if (!template.opsForValue().get(key).equals(code)) {
            return Result.fail(InfoCode.UNPROCESSABLE_ENTITY, InfoCode.MESSAGE_UNPROCESSABLE_ENTITY, System.currentTimeMillis());
        }
        DtsAdmin admin = dtsAdminMapper.login(name, MD5Util.string2MD5(password));
        if (admin == null) {
            return Result.fail(InfoCode.QUERY_EMPTY, InfoCode.MESSAGE_QUERY_EMPTY, System.currentTimeMillis());
        }
        DtsAdminVO vo = new DtsAdminVO();
        BeanUtil.copyProperties(admin, vo);
        // 会话登录：参数填写要登录的账号id，建议的数据类型：long | int | String， 不可以传入复杂类型，如：User、Admin 等等
        // 第1步，先登录上
//        StpUtil.login(admin.getId(),"PC");
        //调用此方法登录后，同设备的会被顶下线（不同设备不受影响），再次访问系统时会抛出 NotLoginException 异常，场景值=-4
        StpKit.ADMIN.login(admin.getId(), "PC");
        // 第2步，获取 Token  相关参数
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        Map map1 = new HashMap<>();
        map1.put("adminInfo", vo);
        map1.put("saToken", tokenInfo);
        return Result.result(InfoCode.OK, InfoCode.MESSAGE_OK, map1, System.currentTimeMillis());
    }

    /**
     * 获得图形验证码
     *
     * @return
     */
    @Override
    public Result getCode(String key) {
        this.key = key;
        String imageCode = ImageCode.createImageCode();
        String number = ImageCode.getNumber();
        //设置图形验证码有效期(3分钟)
        template.opsForValue().set(key, number, 3, TimeUnit.MINUTES);
        return Result.result(InfoCode.CREATED, InfoCode.MESSAGE_CREATED, imageCode, System.currentTimeMillis());
    }


    @Override
    public DtsAdmin getAllInfoById(Integer id) {
        DtsAdmin admins = dtsAdminMapper.getAllInfoById(id);
        return admins;
    }

    @Override
    public Map getDtsAdminList(DtsAdminDto dto) {
        // Redis Key 存储，包含页码和条件
        StringBuilder redisKeyBuilder = new StringBuilder("DtsAdminList");


        if (dto.getUsername() != null && !dto.getUsername().isEmpty()) {
            redisKeyBuilder.append(":Username:").append(dto.getUsername());
        }


        redisKeyBuilder.append(":page:").append(dto.getPageNum());
        String redisKey = redisKeyBuilder.toString();
        List<DtsAdmin> adminList = null;
        // 检查 Redis 中是否存在当前页的数据
        if (redisUtil.hasKey(redisKey)) {

            adminList = (List<DtsAdmin>) redisUtil.get(redisKey);
            Map<String, Object> map1 = new HashMap<>();
            // 获取存储的总数

            map1.put("list", adminList);
            map1.put("total", redisUtil.get("DtsAdminList:total")); // 使用从 Redis 获取的总数
            map1.put("pageNum", dto.getPageNum());
            map1.put("pageSize", dto.getPageSize());
            return map1;
        } else {
            // 开始分页
            Page page = PageHelper.startPage(dto.getPageNum(), dto.getPageSize());

            adminList = dtsAdminMapper.getDtsAdminList(dto);
            Map<String, Object> map = new HashMap<>();
            // 计算总数
//            long total = page.getTotal();

            // 将查询结果放入 Redis，设置过期时间，例如：1小时
            redisUtil.set(redisKey, adminList, 3600);

            redisUtil.set("DtsAdminList:total", dtsAdminMapper.getDtsAdminCount(), 3600);

            map.put("list", page.getResult());
            map.put("total", page.getTotal()); // 使用从数据库计算的总数
            map.put("totalPage", page.getPages());
            map.put("pageNum", page.getPageNum());
            map.put("pageSize", page.getPageSize());
            return map;
        }
    }

    @Override
    public int AdminUsernameCount(String username) {

        return dtsAdminMapper.AdminUsernameCount(username);
    }

    @Override
    public int createAdmin(DtsAdmin admin) {
        // 首先检查是否有任何以 "DtsAdList:" 开头的键
        Set<String> keys = redisUtil.keys("DtsAdminList:*");
        if (!keys.isEmpty()) {
            // 删除所有匹配的键
            for (String key : keys) {
                redisUtil.del(key);
            }
        }
        return dtsAdminMapper.createAdmin(admin);
    }

    @Override
    public boolean changeAdminInfoById(DtsAdmin admin) {
        // 首先检查是否有任何以 "DtsAdList:" 开头的键
        Set<String> keys = redisUtil.keys("DtsAdminList:*");
        if (!keys.isEmpty()) {
            // 删除所有匹配的键
            for (String key : keys) {
                redisUtil.del(key);
            }
        }
        return dtsAdminMapper.changeAdminInfoById(admin);
    }

    @Override
    public int deleteAdmin(DtsAdmin admin) {
        // 首先检查是否有任何以 "DtsAdList:" 开头的键
        Set<String> keys = redisUtil.keys("DtsAdminList:*");
        if (!keys.isEmpty()) {
            // 删除所有匹配的键
            for (String key : keys) {
                redisUtil.del(key);
            }
        }
        return dtsAdminMapper.deleteAdmin(admin);
    }

    @Override
    public int updateRoleAdmin(DtsRole role) {
        // 首先检查是否有任何以 "DtsAdList:" 开头的键
        Set<String> keys = redisUtil.keys("DtsAdminList:*");
        if (!keys.isEmpty()) {
            // 删除所有匹配的键
            for (String key : keys) {
                redisUtil.del(key);
            }
        }
        return dtsAdminMapper.updateRoleAdmin(role);
    }

}

